<script lang="ts" setup>
import SparkMD5 from "spark-md5";
const spark = new SparkMD5.ArrayBuffer();
const CHUNK_SIZE = 1024 * 1024 * 1;

const createFileChunks = (file: File) => {
  let cur = 0;
  const chunks = [];
  while (cur < file.size) {
    chunks.push(file.slice(cur, cur + CHUNK_SIZE));
    cur += CHUNK_SIZE;
  }
  return chunks;
};

const calcHash = (chunks: Blob[]) => {
  return new Promise((resolve) => {
    const targets: Blob[] = [];
    chunks.forEach((chunk, index) => {
      if (index === 0 || index === chunks.length - 1) {
        targets.push(chunk);
      } else {
        // 中间两个字节
        // slice 特点：包前不包后、小数点向下取整
        targets.push(chunk.slice(0, 2));
        targets.push(chunk.slice(CHUNK_SIZE / 2, CHUNK_SIZE / 2 + 2));
        targets.push(chunk.slice(CHUNK_SIZE - 2, CHUNK_SIZE));
      }
    });
    const fileReader = new FileReader();
    fileReader.readAsArrayBuffer(new Blob(targets));
    fileReader.onload = () => {
      spark.append(fileReader.result as ArrayBuffer);
      resolve(spark.end());
    };
  });
};

const handleChange = async (e: Event) => {
  const files = (e.target as HTMLInputElement).files;
  if (!files) return;
  const chunks = createFileChunks(files[0]);
  const hash = await calcHash(chunks);
  console.log(hash);
};
</script>

<template>
  <input type="file" @change="handleChange" />
</template>
